package matchthreegame.gameLogic;

import java.util.ArrayList;
import java.util.HashMap;

import matchthreegame.utils.HeroConditions;
import matchthreegame.utils.HeroSkills;

import com.smartfoxserver.v2.entities.data.SFSArray;
import com.smartfoxserver.v2.entities.data.SFSObject;

public class Hero {

	private static final int NUMBER_OF_COOKIE_TYPES = 6;
	
	public int cookieType1Counter;
	public int cookieType2Counter;
	public int cookieType3Counter;
	public int cookieType4Counter;
	public int cookieType5Counter;
	public int cookieType6Counter;
	public int type;
	public int produces;
	public int attack;
	private HashMap<Integer, Integer> heroSkillOnMyself;
	private HashMap<Integer, Integer> heroSkillOnOtherPlayer;
	private HashMap<Integer, Integer> heroUsageConditions;
	private boolean wasHeroUsedThisWave = false;

	public Hero(int type, final int produces, final int attack) {
		
		this.cookieType1Counter = 0;
		this.cookieType2Counter = 0;
		this.cookieType3Counter = 0;
		this.cookieType4Counter = 0;
		this.cookieType5Counter = 0;
		this.cookieType6Counter = 0;
		this.type = type;
		this.produces = produces;
		this.attack = attack;
		
		/* 
		// Old way ...
   		this.heroUsageConditions = HeroConditions.getHeroConditionsForType(this.type);
		//Get hero skills on given type
		ArrayList<HashMap<Integer, Integer>> heroSkills = HeroSkills.getHeroSkillsForType(this.type);
		this.heroSkillOnMyself = heroSkills.get(0);
		this.heroSkillOnOtherPlayer = heroSkills.get(1); 
		 */
		
		this.heroUsageConditions =  new HashMap<Integer, Integer>(){{
			put(1, 0);
			put(2, 0);
			put(3, 0);
			put(4, 0);
			put(5, 4);
			put(6, 4);
		}}; 
		
		this.heroSkillOnMyself = new HashMap<Integer, Integer>(){{
			put(1, produces);
			put(2, produces);
			put(3, produces);
			put(4, produces);
			put(5, 0);
			put(6, 0);
		}}; 
		this.heroSkillOnOtherPlayer = new HashMap<Integer, Integer>(){{
			put(1, attack);
			put(2, attack);
			put(3, attack);
			put(4, attack);
			put(5, 0);
			put(6, 0);
		}}; 
		
	}
	
	
	// Calculate score for particular Chain
	public void calculateScoreForChain(GameChain chain, Player myself, Player otherPlayer)
	{

		int valueOfCookie = 1;

		for (GameCookie cookie : chain.cookies) {

			switch (cookie.cookieType) {
			case 1:
				cookieType1Counter += valueOfCookie;
				break;
			case 2:
				cookieType2Counter += valueOfCookie;
				break;
			case 3:
				cookieType3Counter += valueOfCookie;
				break;
			case 4:
				cookieType4Counter += valueOfCookie;
				break;
			case 5:
				cookieType5Counter += valueOfCookie;
				break;
			case 6:
				cookieType6Counter += valueOfCookie;
				break;

			default:
				break;
			}

		}
		
		// perform HeroSkill ONLY once per Wave
		if ( wasHeroUsedThisWave == true ) {
			return;
		}
		
		if ( shouldUseHero() ) {
			performHeroSkill(myself, otherPlayer);
		}

	}
	
	private void performHeroSkill(Player myself, Player otherPlayer) {
		
		// change cookieCounters with + or - values 
		myself.useHeroSkill(heroSkillOnMyself);
		otherPlayer.useHeroSkill(heroSkillOnOtherPlayer);
		
		this.wasHeroUsedThisWave = true;
		decreaseCookieCounters();
		
	}
	
	// Determines when Hero Should be USED
	private boolean shouldUseHero() {
		
		Integer cookieType1Target = heroUsageConditions.get(1);
		Integer cookieType2Target = heroUsageConditions.get(2);
		Integer cookieType3Target = heroUsageConditions.get(3);
		Integer cookieType4Target = heroUsageConditions.get(4);
		Integer cookieType5Target = heroUsageConditions.get(5);
		Integer cookieType6Target = heroUsageConditions.get(6);
		
		// Return False if some of the counters is less than the target value
		if ( cookieType1Counter < cookieType1Target ) {
			return false;
		} else if ( cookieType2Counter < cookieType2Target ) {
			return false;
		} else if ( cookieType3Counter < cookieType3Target ) {
			return false;
		} else if ( cookieType4Counter < cookieType4Target ) {
			return false;
		} else if ( cookieType5Counter < cookieType5Target ) {
			return false;
		} else if ( cookieType6Counter < cookieType6Target ) {
			return false;
		}
		
		return true;
				
	}
	
	
	/*
	 * Reset all counters to 0
	 */
	public void resetCounters()
	{

		this.cookieType1Counter = 0;
		this.cookieType2Counter = 0;
		this.cookieType3Counter = 0;
		this.cookieType4Counter = 0;
		this.cookieType5Counter = 0;
		this.cookieType6Counter = 0;

	}
	
	
	public SFSArray heroCountersAsSFSArray() {
		
		// at index 0 is heroType
	    // at indexes from 1 to 6 are values for the cookies counters
		SFSArray cookiesScoreSfsArray = new SFSArray();
		cookiesScoreSfsArray.addInt(this.type);
		cookiesScoreSfsArray.addInt(this.cookieType1Counter);
		cookiesScoreSfsArray.addInt(this.cookieType2Counter);
		cookiesScoreSfsArray.addInt(this.cookieType3Counter);
		cookiesScoreSfsArray.addInt(this.cookieType4Counter);
		cookiesScoreSfsArray.addInt(this.cookieType5Counter);
		cookiesScoreSfsArray.addInt(this.cookieType6Counter);
		
		return cookiesScoreSfsArray;
		
	}
	
	
	private void decreaseCookieCounters() {
		
		Integer cookieType1Target = heroUsageConditions.get(1);
		Integer cookieType2Target = heroUsageConditions.get(2);
		Integer cookieType3Target = heroUsageConditions.get(3);
		Integer cookieType4Target = heroUsageConditions.get(4);
		Integer cookieType5Target = heroUsageConditions.get(5);
		Integer cookieType6Target = heroUsageConditions.get(6);
		
		cookieType1Counter -= cookieType1Target;
		cookieType2Counter -= cookieType2Target;
		cookieType3Counter -= cookieType3Target;
		cookieType4Counter -= cookieType4Target;
		cookieType5Counter -= cookieType5Target;
		cookieType6Counter -= cookieType6Target;
		
	}
	

	// makes all Negative values to be 0
	public void correctNegativeCounters() {

		cookieType1Counter = cookieType1Counter < 0 ? 0 : cookieType1Counter;
		cookieType2Counter = cookieType2Counter < 0 ? 0 : cookieType2Counter;
		cookieType3Counter = cookieType3Counter < 0 ? 0 : cookieType3Counter;
		cookieType4Counter = cookieType4Counter < 0 ? 0 : cookieType4Counter;
		cookieType5Counter = cookieType5Counter < 0 ? 0 : cookieType5Counter;
		cookieType6Counter = cookieType6Counter < 0 ? 0 : cookieType6Counter;

	}


	public boolean wasHeroUsedThisWave() {
		
		return wasHeroUsedThisWave;
		
	}
	
	public void setWasHeroUsedThisWave(boolean wasHeroUsedThisWave) {
		
		this.wasHeroUsedThisWave = wasHeroUsedThisWave;
		
	}
	
	public SFSArray getUsageConditionsAsSFSArray() {
		
		SFSArray sfsUsageConditions = SFSArray.newInstance();

		for (int i = 1; i <= NUMBER_OF_COOKIE_TYPES; i++) {

			// get the value of the cookieType
			Integer cookieTypeConditionValue = heroUsageConditions.get(i);

			// set ConditionValue for key current cookieType ( example: { '1':14, '2':43, '3': 0 ... } ) 
			SFSObject sfsCookieTypeConditionValue = SFSObject.newInstance();
			sfsCookieTypeConditionValue.putInt(Integer.toString(i), cookieTypeConditionValue.intValue());

			sfsUsageConditions.addSFSObject(sfsCookieTypeConditionValue);
		}
		
		return sfsUsageConditions;
		
	}
	
	
	public SFSArray getSkillsOnMyselfAsSFSArray() {
		
		SFSArray sfsSkillsOnMyself = SFSArray.newInstance();
		
		for (int i = 1; i <= NUMBER_OF_COOKIE_TYPES; i++) {
			
			// get the value of the cookieType
			Integer cookieTypeConditionValue = heroSkillOnMyself.get(i);
			
			// set ConditionValue for key current cookieType ( example: { '1':14, '2':43, '3': 0 ... } ) 
			SFSObject sfsCookieTypeSkillValue = SFSObject.newInstance();
			sfsCookieTypeSkillValue.putInt(Integer.toString(i), cookieTypeConditionValue.intValue());
			
			sfsSkillsOnMyself.addSFSObject(sfsCookieTypeSkillValue);
			
		}
		
		return sfsSkillsOnMyself;
		
	}
	
	
	public SFSArray getSkillsOnOtherPlayerAsSFSArray() {
		
		SFSArray sfsSkillsOnOtherPlayer = SFSArray.newInstance();
		
		for (int i = 1; i <= NUMBER_OF_COOKIE_TYPES; i++) {
			
			// get the value of the cookieType
			Integer cookieTypeConditionValue = heroSkillOnOtherPlayer.get(i);
			
			// set ConditionValue for key current cookieType ( example: { '1':14, '2':43, '3': 0 ... } ) 
			SFSObject sfsCookieTypeSkillValue = SFSObject.newInstance();
			sfsCookieTypeSkillValue.putInt(Integer.toString(i), cookieTypeConditionValue.intValue());
			
			sfsSkillsOnOtherPlayer.addSFSObject(sfsCookieTypeSkillValue);
			
		}
		
		return sfsSkillsOnOtherPlayer;
		
	}
	
	
	public void addComboCookies(int comboCookiesToBeAdded, Player myself, Player otherPlayer ) {
		
		//update counters
		this.cookieType1Counter += comboCookiesToBeAdded;
		this.cookieType2Counter += comboCookiesToBeAdded;
		this.cookieType3Counter += comboCookiesToBeAdded;
		this.cookieType4Counter += comboCookiesToBeAdded;
		this.cookieType5Counter += comboCookiesToBeAdded;
		this.cookieType6Counter += comboCookiesToBeAdded;
		
		// perform HeroSkill ONLY once per Wave
		if ( wasHeroUsedThisWave == true ) {
			return;
		}

		if ( shouldUseHero() ) {
			performHeroSkill(myself, otherPlayer);
		}

	}
	
}
